﻿using System;
using System.Collections.Generic;
using System.Text;
using NUnit.Framework;
using System.Transactions;
using Microsoft.Practices.EnterpriseLibrary.Data;
using FriendsNearby.Services.Entities;
using InSTEDD.Labs.Geo;

namespace FriendsNearby.Services.Tests
{
    [TestFixture]
    public class LocationServiceFixture
    {
        TransactionScope testContextTransaction;
        LocationService locationService;
        Database database;
		Guid userID;

        [SetUp]
        public void SetUp()
        {
            testContextTransaction = new TransactionScope();

            database = DatabaseFactory.CreateDatabase("FriendsNearbyDB");

            // Temporaly clear DB
            database.ExecuteNonQuery(System.Data.CommandType.Text, "DELETE FROM UserLocation");
            database.ExecuteNonQuery(System.Data.CommandType.Text, "DELETE FROM UserLocationHistory");
			userID = Guid.NewGuid();

			database.ExecuteNonQuery(System.Data.CommandType.Text, string.Format("INSERT INTO UserRegistry (UserID) VALUES ('{0}')", userID.ToString("B")));
            //
            FriendsNearbySystem fnbFacade = new FriendsNearbySystem();
            locationService = fnbFacade.GetService<ILocationService, LocationService>();
        }

        [TearDown]
        public void TearDown()
        {
            //testContextTransaction.Complete();
            testContextTransaction.Dispose();
        }

        [Test]
        public void NonRegisteredUserReturnsNullLocation()
        {
            LocationInfo info = locationService.GetCurrentLocation(Guid.NewGuid());
            Assert.IsNull(info.Location);
        }

        [Test]
        public void StoredNewLocationCanBeRetrieved()
        {
			locationService.SetCurrentLocation(userID, new LatLong(11.0f, -15.0f));
			LocationInfo info = locationService.GetCurrentLocation(userID);
			Assert.AreEqual(userID, info.UserID);
            Assert.IsNotNull(info.Location);
            Assert.AreEqual(11.0f, info.Location.Lat);
            Assert.AreEqual(-15.0f, info.Location.Long);
        }

        [Test]
        public void LocationCanBeOverwritten()
		{
			locationService.SetCurrentLocation(userID, new LatLong(2.0f, -2.0f));
			locationService.SetCurrentLocation(userID, new LatLong(17.0f, -23.0f));
			LocationInfo info = locationService.GetCurrentLocation(userID);

			Assert.AreEqual(userID, info.UserID);
            Assert.IsNotNull(info.Location);
            Assert.AreEqual(17.0f, info.Location.Lat);
            Assert.AreEqual(-23.0f, info.Location.Long);
        }


        [Test]
        public void LocationHistoryCanBeRetrievedAtSpecificPoint()
        {

            database.ExecuteNonQuery(System.Data.CommandType.Text,
                string.Format("INSERT INTO UserLocationHistory (UserID, Lat, Long, Timestamp) values ('{0}', 10, 10, '2008-01-01')",  userID.ToString("B")));
            database.ExecuteNonQuery(System.Data.CommandType.Text,
				string.Format("INSERT INTO UserLocationHistory (UserID, Lat, Long, Timestamp) values ('{0}', 20, 20, '2008-02-02')", userID.ToString("B")));
            database.ExecuteNonQuery(System.Data.CommandType.Text,
				string.Format("INSERT INTO UserLocationHistory (UserID, Lat, Long, Timestamp) values ('{0}', 30, 30, '2008-03-03')", userID.ToString("B")));
            database.ExecuteNonQuery(System.Data.CommandType.Text,
				string.Format("INSERT INTO UserLocationHistory (UserID, Lat, Long, Timestamp) values ('{0}', 40, 40, '2008-04-04')", userID.ToString("B")));

			LocationInfo info1 = locationService.GetLocationAt(userID, DateTime.Parse("2008-01-01"));
			LocationInfo info2 = locationService.GetLocationAt(userID, DateTime.Parse("2008-02-02"));
			LocationInfo info3 = locationService.GetLocationAt(userID, DateTime.Parse("2008-03-03"));
			LocationInfo info4 = locationService.GetLocationAt(userID, DateTime.Parse("2008-04-04"));

            Assert.AreEqual(10, info1.Location.Lat);
            Assert.AreEqual(10, info1.Location.Long);
            Assert.AreEqual(20, info2.Location.Lat);
            Assert.AreEqual(20, info2.Location.Long);
            Assert.AreEqual(30, info3.Location.Lat);
            Assert.AreEqual(30, info3.Location.Long);
            Assert.AreEqual(40, info4.Location.Lat);
            Assert.AreEqual(40, info4.Location.Long);
        }
    }
}
